//交互的接口
package role

import (
	"fmt"
	"sanguo/node/common/DropPool"
	"sanguo/node/common/GlobalConstData"
	"sanguo/node/common/actionEvent"
	"sanguo/node/common/attr"
	"sanguo/node/common/com_type"
	"sanguo/node/node_game/common/IDGen"
	"sanguo/node/node_game/module/role/InstanceZone"
	"sanguo/node/node_game/module/role/bag"
	"sanguo/node/node_game/module/role/battleGround"
	table_BattleLevel "sanguo/node/table/excel/table/BattleLevel"
	table_Item "sanguo/node/table/excel/table/Item"
	table_RoleLev "sanguo/node/table/excel/table/RoleLevel"
	table_Soul "sanguo/node/table/excel/table/Soul"
	table_Weapon "sanguo/node/table/excel/table/Weapon"
	table_mission "sanguo/node/table/mission"
)

/***************************** attr *******************************/
func (this *Role) AddExp(count int64) {
	if count <= 0 {
		return
	}
	CurrentExp, _ := this.attr.GetAttr(attr.CurrentExp)
	totalExp, _ := this.attr.GetAttr(attr.TotalExp)
	CurrentExp += count
	totalExp += count

	befLevel, _ := this.attr.GetAttr(attr.Level)
	currentLevel, _ := this.GetRoleAttr().GetAttr(attr.Level)

	if currentLevel < GlobalConstData.RoleMaxLevel {
		NeedExp := int64(table_RoleLev.Table_.IDMap[int32(currentLevel)].Exp)
		for currentLevel < GlobalConstData.RoleMaxLevel && CurrentExp >= NeedExp {
			CurrentExp -= NeedExp
			currentLevel += 1
			this.GetRoleAttr().SetAttr(attr.Level, currentLevel)
			if currentLevel < GlobalConstData.RoleMaxLevel {
				NeedExp = int64(table_RoleLev.Table_.IDMap[int32(currentLevel)].Exp)
			} else {
				if CurrentExp >= NeedExp {
					CurrentExp = int64(table_RoleLev.Table_.IDMap[int32(currentLevel)].Exp) - 1
				}
			}
		}
	} else {
		CurrentExp = int64(table_RoleLev.Table_.IDMap[int32(currentLevel)].Exp) - 1
	}

	this.attr.SetAttr(attr.CurrentExp, CurrentExp)
	this.attr.SetAttr(attr.UpperExp, int64(table_RoleLev.Table_.IDMap[int32(currentLevel)].Exp))
	this.attr.SetAttr(attr.TotalExp, totalExp)

	//等级改变处理
	if currentLevel != befLevel {
		this.SetLev(int32(currentLevel))

		//将外观传到map
		this.ChangeOutline()

		//与等级限制的任务
		//missions := this.GetRoleMission().GetUnAcceptMission()
		//for _, v := range missions {
		//	this.GetRoleMission().MissionCanAccept(v)
		//}

		//加技能点
		//this.AddSkillPoint(int32(laterLevel - befLevel))

		this.TotalBattleAttr()

	}
}

//体力
func (this *Role) AddActionPoint(count int64) {
	if count <= 0 {
		return
	}
	this.attr.AddAttr(attr.ActionPoint, count, 0, GlobalConstData.ActionPointMax)
}

func (this *Role) UseActionPoint(count int64) bool {
	if count <= 0 {
		return false
	}

	ap, _ := this.attr.GetAttr(attr.ActionPoint)

	if ap < count {
		return false
	}

	ap -= count
	this.attr.SetAttr(attr.ActionPoint, ap)

	return true
}

//星币
func (this *Role) AddGold(count int64) {
	if count <= 0 {
		return
	}
	gold, _ := this.attr.GetAttr(attr.Gold)
	gold += count
	this.attr.SetAttr(attr.Gold, gold)
}

func (this *Role) UseGold(count int64) bool {
	if count <= 0 {
		return false
	}

	gold, _ := this.attr.GetAttr(attr.Gold)
	if gold < count {
		return false
	}

	gold -= count
	this.attr.SetAttr(attr.Gold, gold)

	return true
}

//钻石
func (this *Role) AddDiamond(count int64) {
	if count <= 0 {
		return
	}
	diamond, _ := this.attr.GetAttr(attr.Diamond)
	diamond += count
	this.attr.SetAttr(attr.Diamond, diamond)
}

func (this *Role) UseDiamond(count int64) bool {
	if count <= 0 {
		return false
	}

	diamond, _ := this.attr.GetAttr(attr.Diamond)
	if diamond < count {
		return false
	}

	diamond -= count
	this.attr.SetAttr(attr.Diamond, diamond)

	return true
}

/*************************** InstanceZone ************************************/

func (this *Role) GetInstanceZone() *InstanceZone.InstanceZone {
	return this.instanceZone
}

func (this *Role) EnterInstanceZone(ID, InitType int32) *InstanceZone.InstanceZone {
	//读表 前置条件
	IZDef := table_BattleLevel.Table_.IDMap[ID]

	//原地图位置
	oldMapID := this.data.MapID
	X := this.data.X
	Y := this.data.Y
	Z := this.data.Z
	Angle := this.data.Angle

	this.instanceZone = InstanceZone.InitInstanceZone(ID, InitType, oldMapID, X, Y, Z, Angle)
	if this.instanceZone == nil {
		return nil
	}
	/*
		进入副本地图
		如果为单机副本角色仅离开原地图
		多人副本 角色进入对应地图
	*/
	if IZDef.IsReconnet { //多人
		mapID := IZDef.MapID
		pos := IZDef.Position
		anglge := IZDef.Angle
		fmt.Println("IsReconnet == true", mapID, pos, anglge)
		if this.NodeMap != nil {
			this.LeaveMap()
		}
		//this.EnterMap()
	} else {
		fmt.Println("IsReconnet == false", this.data.MapID)
		this.LeaveMap()
	}

	return this.instanceZone
}

func (this *Role) ClearInstanceZone() {
	//任务未完成
	insZone := this.GetInstanceZone()
	if insZone != nil {
		if insZone.InitType != com_type.InstanceZone_YhBattleGround {
			//退回到原地图
			this.data.MapID = insZone.OldMapID
			this.data.X = insZone.OldPosX
			this.data.Y = insZone.OldPosY
			this.data.Z = insZone.OldPosZ
			this.data.Angle = insZone.OldPosAngle
		}
		this.instanceZone = nil
	}

}

/*************************** BattleGround ***************************************/
func (this *Role) GetBattleGround() *battleGround.BattleGround {
	return this.battleGround
}

func (this *Role) InitBattleGround(battleGroundId, power int32) {
	mapID := this.GetMapID()
	x, y, z := this.GetPos()
	angle := this.GetAngle()
	this.battleGround = battleGround.InitBattleGround(battleGroundId, power, mapID, x, y, z, angle)
}

func (this *Role) ClearBattleGround() {
	battleGround := this.battleGround
	if battleGround != nil {
		//退回到原地图
		this.data.MapID = battleGround.OldMapID
		this.data.X = battleGround.OldPosX
		this.data.Y = battleGround.OldPosY
		this.data.Z = battleGround.OldPosZ
		this.data.Angle = battleGround.OldPosAngle

		this.battleGround = nil
	}

}

/**************************** Item *********************************/

//添加物品
func (this *Role) AddItem(items map[int32]int32) {
	if len(items) == 0 {
		return
	}
	for id, count := range items {
		if table_Item.Table_.IDMap[id] == nil {
			continue
		}
		this.GetRoleItem().AddItem(id, count)
	}
	this.OnItemDirty()

}

/****************************** Weapon *********************************/

func (this *Role) AddWeapon(weapons map[int32]int32) {
	if len(weapons) == 0 {
		return
	}

	needSend := false
	content := fmt.Sprintf("恭喜玩家[%s]在[我也不知道是哪儿]获得 ", this.GetName())

	for weaponId, count := range weapons {
		weaponDef := table_Weapon.Table_.IDMap[weaponId]
		if weaponDef == nil {
			continue
		}

		if weaponDef.DefaultStar >= com_type.Rarity_Good {
			content += "[" + weaponDef.Name + "] "
			needSend = true
		}

		//武器转化碎片
		weapon := this.GetRoleWeapon().GetWeapon(weaponId)
		if weapon == nil {
			this.GetRoleWeapon().AddWeapon(weaponId)
			weaponShards := (int32(count) - int32(1)) * weaponDef.TransformShards
			if weaponShards != 0 {
				ws := map[int32]int32{weaponId: weaponShards}
				this.AddWeaponShard(ws)
			}

			//武器激活属性
			if weaponDef.ActiveType != 0 {
				if weaponDef.ActiveType == com_type.WeaponActive_Partner { //伙伴

				} else if weaponDef.ActiveType == com_type.WeaponActive_Mecha { //机甲

				}
			}

		} else {
			weaponShards := int32(count) * weaponDef.TransformShards
			ws := map[int32]int32{weaponId: weaponShards}
			this.AddWeaponShard(ws)
		}
	}

	if needSend {
		this.OnSystemMsg(content)
	}

	this.OnWeaponDirty()
	this.OnWeaponShardDirty()

	this.TotalBattleAttr()
}

/************************** WeaponShard ****************************************/
func (this *Role) AddWeaponShard(weaponShards map[int32]int32) {
	if len(weaponShards) == 0 {
		return
	}
	for id, count := range weaponShards {
		if table_Weapon.Table_.IDMap[id] == nil {
			continue
		}
		this.GetRoleWeaponShard().AddWeaponShard(id, count)
		WeaponDef := table_Weapon.Table_.IDMap[id]
		this.GetRoleStarMap().AddStarMapShard(WeaponDef.Rarity, count)
	}
	this.OnWeaponShardDirty()
	this.OnStarMapDirty()
}

/***************************** Soul ********************************/

//武魂
func (this *Role) AddSoul(souls map[int32]int32) {
	if len(souls) == 0 {
		return
	}
	for configId, count := range souls {
		soulDef := table_Soul.Table_.IDMap[configId]
		if soulDef == nil {
			continue
		}
		for i := 0; i < int(count); i++ {
			soulId, _ := IDGen.SoulGenID()
			soul := bag.FuncNewSoul(soulId, configId)
			this.GetRoleSoul().AddSoul(soul)
		}
	}
	this.OnSoulDirty()
}

/******************************** StarMap *****************************/
func (this *Role) AddStarMoon(count int32) {
	if count <= 0 {
		return
	}
	this.GetRoleStarMap().AddStarMoon(count)
	this.OnStarMapDirty()
}

/******************************** Mission *****************************/

//接取任务
func (this *Role) AcceptMission(missionId int32) bool {
	if !this.GetRoleMission().AcceptMission(missionId) {
		return false
	}

	return true
}

//交付任务
func (this *Role) CompleteMission(missionId int32) bool {

	def := table_mission.GetDef(missionId)
	if nil != def {
		deliverAction := def.DeliverInfo.DeliverConditionEvent
		for _, v := range deliverAction {
			if !actionEvent.DoLimitActionEvent(v.ActionName, this, v.Params) {
				return false
			}
		}

		for _, v := range def.DeliverInfo.DeliverConditionEvent {
			if v.ActionName == "ItemLimit" {
				//
			}
		}
	}

	if !this.GetRoleMission().CompleteMission(missionId) {
		return false
	}

	return true
}

/************************** skill **********************************/
func (this *Role) AddSkillPoint(power int32) {
	this.GetRoleSkill().AddSkillPoint(power)
	this.OnSkillDirty()
}

/*********************** Award **********************************/

func (this *Role) GiveOutAward(award *DropPool.Award) {
	if award == nil {
		return
	}
	exp := int32(0)
	gold := int32(0)
	starMoon := int32(0)

	items := map[int32]int32{}
	weapons := map[int32]int32{}
	souls := map[int32]int32{}
	weaponShards := map[int32]int32{}

	for _, v := range award.Infos {
		switch v.Type {
		case com_type.Drop_Exp:
			exp += v.Count
		case com_type.Drop_Gold:
			gold += v.Count
		case com_type.Drop_Moon:
			starMoon += v.Count
		case com_type.Drop_Item:
			items[v.ID] = v.Count
		case com_type.Drop_Weapon:
			weapons[v.ID] = v.Count
		case com_type.Drop_Soul:
			souls[v.ID] = v.Count
		case com_type.Drop_WeaponShard:
			weaponShards[v.ID] = v.Count
		}
	}
	this.AddExp(int64(exp))
	this.AddGold(int64(gold))
	this.AddStarMoon(starMoon)

	this.AddItem(items)
	this.AddWeapon(weapons)
	this.AddSoul(souls)
	this.AddWeaponShard(weaponShards)
}
